package org.ucas.faker.web.utils.tech;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

public class FeatEffStatics {
	HashMap<String,Integer> map = null;
	HashMap<String,Integer> map_fea = null;
	HashMap<String,Integer> map_eff = null;
	public FeatEffStatics(){
		map = new HashMap<String,Integer>();
		map_fea = new HashMap<>();
		map_eff = new HashMap<>();
	}
	
	private String postTopic(String text){
		String res = "";
		CloseableHttpClient httpclient = HttpClients.createDefault();
		/*
		HttpGet httpGet = new HttpGet("http://targethost/homepage");
		CloseableHttpResponse response1 = httpclient.execute(httpGet);
		// The underlying HTTP connection is still held by the response object
		// to allow the response content to be streamed directly from the network socket.
		// In order to ensure correct deallocation of system resources
		// the user MUST call CloseableHttpResponse#close() from a finally clause.
		// Please note that if response content is not fully consumed the underlying
		// connection cannot be safely re-used and will be shut down and discarded
		// by the connection manager. 
		try {
		    System.out.println(response1.getStatusLine());
		    HttpEntity entity1 = response1.getEntity();
		    // do something useful with the response body
		    // and ensure it is fully consumed
		    EntityUtils.consume(entity1);
		} finally {
		    response1.close();
		}
*/
		HttpPost httpPost = new HttpPost("http://47.95.255.72:8999/get_topic");
		//httpPost.addHeader("Content-Type","text/html;charset=UTF-8");
	
		List <NameValuePair> nvps = new ArrayList <NameValuePair>();
		List<NameValuePair> valuePairs = new ArrayList<NameValuePair>(1);
		valuePairs.add(new BasicNameValuePair("paragraph", text));
		
		CloseableHttpResponse response2=null;
		try {
			UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(valuePairs, "UTF-8");
			
			httpPost.setEntity(formEntity);
			response2 = httpclient.execute(httpPost);
		    //System.out.println(response2.getStatusLine());
		    HttpEntity entity2 = response2.getEntity();
		    //System.out.println(EntityUtils.toString(entity2,"UTF-8"));
		    res = EntityUtils.toString(entity2,"UTF-8");
		    // do something useful with the response body
		    // and ensure it is fully consumed
		    EntityUtils.consume(entity2);
		} catch(Exception e){
			
		}
		finally {
		    //response2.close();
		}
		
		return res;
	}
	
	private void CountOne(String branches,String effects){
		List<String> lf = new ArrayList<>();
		List<String> le = new ArrayList<>();
		
		for(String s:branches.split("#")){
			lf.add(s);
		}
		for(String s:effects.split("#")){
			le.add(s);
		}
		CountOne(lf,le);
	}
	
	private void CountOne(List<String> lf,List<String> le){
		for(String fea:lf){
			if(fea.equals("")) continue;
			if(!map_fea.containsKey(fea)) map_fea.put(fea, 1);
			else{
				map_fea.put(fea, map_fea.get(fea)+1);
			}
		}
		
		for(String eff:le){
			if(eff.equals("")) continue;
			if(!map_eff.containsKey(eff)) map_eff.put(eff, 1);
			else{
				map_eff.put(eff, map_eff.get(eff)+1);
			}
		}
		
		for(String fea:lf){
			if(fea.equals("")) continue;
			for(String eff:le){
				if(eff.equals("")) continue;
				//System.out.println(fea+"#"+eff);
				String key = fea + "#" +eff;
				if(!map.containsKey(key)) map.put(key, 1);
				else{
					map.put(key,map.get(key)+1);					
				}
			}
		}
	}
	public void CountFeaturesAndEffects(List<String> abs){
		for(String s:abs){
			Map<String,String> map = PatentFeaturize.getInstance().featurizeAbstract(s);
			CountOne(map.get("feature"),map.get("effect"));
		}
		
		//DisplayCounts();
		Summary();
	}
	
	public Map<String,List<String> > CountFeaturesAndEffects(List< List<String>> features,List< List<String>> effects){
		for(int i=0;i<features.size();i++){
			CountOne(features.get(i),effects.get(i));
		}
		
		return Summary();
	}
	
	private Map<String,List<String> > Summary(){
		//sort for features
		//System.out.println("\nFeatures Count");
		List<Map.Entry<String, Integer>> list_fea = new ArrayList(map_fea.entrySet());
		Collections.sort(list_fea,new Comparator<Map.Entry<String,Integer>>(){
			@Override
			public int compare(Entry<String,Integer> o1,Entry<String,Integer> o2){
				return o2.getValue().compareTo(o1.getValue());
			}
		});
		
		//map
		//List<Map.Entry<String, Integer>> list_map = new ArrayList(map.entrySet());
		/*Collections.sort(list_map,new Comparator<Map.Entry<String,Integer>>(){
			@Override
			public int compare(Entry<String,Integer> o1,Entry<String,Integer> o2){
				return o2.getValue().compareTo(o1.getValue());
			}
		});*/
		/*final int num_feature1 = 10;
		System.out.println("mytest");
		int feanum1 = 0;
		for(Entry<String,Integer> entry:list_map){
			if(feanum1<num_feature1) feanum1++;
			else break;			
			System.out.print("\t"+entry.getKey()+","+entry.getValue());
			//xlabel.add(entry.getKey());
		}*/

		
		//sort for effect
		List<Map.Entry<String, Integer>> list_eff = new ArrayList(map_eff.entrySet());
		Collections.sort(list_eff,new Comparator<Map.Entry<String,Integer>>(){
			@Override
			public int compare(Entry<String,Integer> o1,Entry<String,Integer> o2){
				return o2.getValue().compareTo(o1.getValue());
			}
		});
		Map<String,List<String>> resmap = new HashMap<>();
		
		List<String> xlabel = new ArrayList<>();
		List<String> ylabel = new ArrayList<>();
		
		final int num_feature = 10;
		final int num_effect = 10;
		int feanum = 0;
		//generate the result
		for(Entry<String,Integer> entry:list_eff){
			if(feanum<num_feature) feanum++;
			else break;			
			//System.out.print("\t"+entry.getKey());
			xlabel.add(entry.getKey());
		}
		//System.out.println();
		resmap.put("xlabel", xlabel);		

		feanum=0;
		for(Entry<String,Integer> entry:list_fea){
			int effnum = 0;
			if(feanum<num_feature) feanum++;
			else break;
			
			//System.out.print(entry.getKey());
			ylabel.add(entry.getKey());
			List<String> val = new ArrayList<>();
			for(Entry<String,Integer> ent_eff:list_eff){
				if(effnum<num_effect) effnum++;
				else break;
				if(map.get(entry.getKey()+"#"+ent_eff.getKey())==null){
					//System.out.print("\t0");
					val.add("0");
				}
				else {
					//System.out.print("\t"+map.get(entry.getKey()+"#"+ent_eff.getKey()));
					val.add(""+map.get(entry.getKey()+"#"+ent_eff.getKey()));
				}
			}
			resmap.put("value"+feanum,val);
			//System.out.println();
		}
		resmap.put("ylabel", ylabel);
		
		List<String> feaandeffnum = new ArrayList<>();
		if(num_feature==num_effect) {		
			feaandeffnum.add(String.valueOf(num_effect));
			resmap.put("feaandeffnum", feaandeffnum);
		}else if(num_feature>num_effect) {
			feaandeffnum.add(String.valueOf(num_effect));
			resmap.put("feaandeffnum", feaandeffnum);
		}else if(num_feature<num_effect) {
			feaandeffnum.add(String.valueOf(num_feature));
			resmap.put("feaandeffnum", feaandeffnum);
		}	
		return resmap;
	}
	
	
	private void DisplayCounts(){
		/*
		for(Entry<String,Integer> entry : map.entrySet()){
			System.out.println(entry.getKey() + "  " + entry.getValue());
		}		
		System.out.println();
		*/
		
		//sort for features
		//System.out.println("\nFeatures Count");
		List<Map.Entry<String, Integer>> list_fea = new ArrayList(map_fea.entrySet());
		
		Collections.sort(list_fea,new Comparator<Map.Entry<String,Integer>>(){
			@Override
			public int compare(Entry<String,Integer> o1,Entry<String,Integer> o2){
				return o2.getValue().compareTo(o1.getValue());
			}
		});
		/*
		//System.out.println("\n\n");
		for(Entry<String,Integer> entry:list_fea){
			System.out.println(entry.getKey() + "  " + entry.getValue());
		}
		*/
		
		//sort for effect
		//System.out.println("\nEffects Count");
		List<Map.Entry<String, Integer>> list_eff = new ArrayList(map_eff.entrySet());
		
		Collections.sort(list_eff,new Comparator<Map.Entry<String,Integer>>(){
			@Override
			public int compare(Entry<String,Integer> o1,Entry<String,Integer> o2){
				return o2.getValue().compareTo(o1.getValue());
			}
		});
		/*
		//System.out.println("\n\n");
		for(Entry<String,Integer> entry:list_eff){
			System.out.println(entry.getKey() + "  " + entry.getValue());
		}
		*/
		List<String> xlabel = new ArrayList<>();
		List<String> ylabel = new ArrayList<>();
		
		final int num_feature = 10;
		final int num_effect = 10;
		int feanum = 0;
		//generate the result
		for(Entry<String,Integer> entry:list_eff){
			if(feanum<num_feature) feanum++;
			else break;			
			System.out.print("\t"+entry.getKey());
			xlabel.add(entry.getKey());
		}
		System.out.println();
		

		feanum=0;
		for(Entry<String,Integer> entry:list_fea){
			int effnum = 0;
			if(feanum<num_feature) feanum++;
			else break;
			System.out.print(entry.getKey());
			for(Entry<String,Integer> ent_eff:list_eff){
				if(effnum<num_effect) effnum++;
				else break;
				if(map.get(entry.getKey()+"#"+ent_eff.getKey())==null){
					System.out.print("\t0");
				}
				else System.out.print("\t"+map.get(entry.getKey()+"#"+ent_eff.getKey()));
			}
			System.out.println();
		}
	}
	public static void main(String [] args){
		try{
			List<String> l = new ArrayList<>();
			l.add("本实用新型公开了一种方型铝壳锂离子电池电芯结构，属于锂离子电池制造领域；旨在提供一种平整度高、极片之间的界面稳定性高、循环性能稳定的卷绕式方型铝壳锂离子电池电芯结构，本实用新型包括有电池正负极片；其特征是：所述电池极片上，根据卷绕半周宽度的间隔，设有涂层空隙。提高了整个电池卷芯的平整性，采用本实用新型电芯结构的电池稳定性高、循环性能稳定性高。适用于锂离子电池的制造领域。");
			l.add("本实用新型公开了一种方型铝壳锂离子电池电芯结构，属于锂离子电池制造领域；旨在提供一种平整度高、极片之间的界面稳定性高、循环性能稳定的卷绕式方型铝壳锂离子电池电芯结构，本实用新型包括有电池正负极片；其特征是：所述电池极片上，根据卷绕半周宽度的间隔，设有涂层空隙。提高了整个电池卷芯的平整性，采用本实用新型电芯结构的电池稳定性高、循环性能稳定性高。适用于锂离子电池的制造领域。");
			l.add("本实用新型揭示了一种防止锂离子电池电芯在PACK模组中转动的钢壳和模组，包括用于放置电芯的钢壳和用于放置所述钢壳的模组，所述钢壳的底部开设有至少一个的凹槽，所述模组的下支架上设有与所述凹槽相对应的凸台。本实用新型的有益效果是：本实用新型的一种防止锂离子电池电芯在PACK模组中转动的钢壳和模组，改变了钢壳底部的平面结构，在保留钢壳底部焊接区的条件下，增加了不同形状及不同个数的凹槽结构，并根据钢壳的凹槽形状制备模组的下支架上的凸台，组装时，将凹槽卡入凸台中，再将模具上支架扣好锁紧，从而达到防止钢壳旋转，造成模具正负极焊点脱离或挣断等问题。");
			l.add("本实用新型公开了一种方型铝壳锂离子电池电芯结构，属于锂离子电池制造领域。旨在提供一种平整度高、极片之间的界面稳定性高、循环性能稳定的卷绕式方型铝壳锂离子电池电芯结构，本实用新型包括有电池正负极片；");
			new FeatEffStatics().CountFeaturesAndEffects(l);
		}
		catch(Exception e){
			
		}
/*
		FeatEffStatics fes = new FeatEffStatics();
		
		List<String> lf = new ArrayList<>();
		List<String> le = new ArrayList<>();
		lf.add("f1");lf.add("f2");lf.add("f3");lf.add("f4");lf.add("f5");
		le.add("e1");le.add("e2");le.add("e3");
		Random rd = new Random();
		final int num_fea = 6;
		final int num_eff = 3;
		
		for(int i=0;i<10;i++){
			lf.clear();
			le.clear();
			int tmp_fea = rd.nextInt(num_fea)+1;
			for(int j=0;j<tmp_fea;j++){
				lf.add("l"+j);
				System.out.print("l"+j+"  ");
			}
			System.out.println();
			int tmp_eff = rd.nextInt(num_eff)+1;
			for(int j=0;j<tmp_eff;j++){
				le.add("e"+j);
				System.out.print("e"+j+"  ");
			}
			System.out.println();
			System.out.println();
			
			fes.CountOne(lf, le);
		}
		
		fes.DisplayCounts();
		//fes.CountOne(lf, le);

		*/
	}

}
